import React, { useState, useRef, useEffect } from 'react';
import { message as antMessage } from 'antd';
import {
  StopOutlined
} from '@ant-design/icons';
import { callXunfeiAPI, createChatContext } from '@/services/xunfei';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import rehypeHighlight from 'rehype-highlight';
import { CopyOutlined } from '@ant-design/icons';
import './chat-fix.less';
import ConversationSidebar from '@/components/ConversationSidebar';
import WelcomeScreen from '@/components/WelcomeScreen';
import MessageCard from '@/components/MessageCard';
import ChatInput from '@/components/ChatInput';
import { Message, Conversation } from '@/types/chat';

/**
 * 新的Markdown渲染组件
 * @description 使用react-markdown及其插件实现安全、功能丰富的渲染
 */
const MarkdownRenderer = ({ content }: { content: string }) => {
  return (
    <ReactMarkdown
      remarkPlugins={[remarkGfm]}
      rehypePlugins={[rehypeHighlight]}
      components={{
        // 自定义代码块渲染，添加语言标识和复制按钮
        code({ node, className, children, ...props }) {
          const match = /language-(\w+)/.exec(className || '');
          const isInline = !match;

          if (isInline) {
            return <code className={className} {...props}>{children}</code>;
          }

          const language = match ? match[1] : 'text';
          return (
            <div className="code-block">
              <div className="code-header">
                <span className="code-language">{language}</span>
                <button
                  className="code-copy"
                  onClick={() => {
                    // 修正复制逻辑 V2：
                    // 使用递归函数遍历AST节点，提取所有纯文本内容。
                    // 这是因为rehype-highlight会将代码包裹在多层<span>中，形成嵌套结构。
                    const extractText = (nodes: any[]): string => {
                      return nodes.map(node => {
                        if (node.type === 'text') {
                          return node.value;
                        }
                        if (node.children && Array.isArray(node.children)) {
                          return extractText(node.children);
                        }
                        return '';
                      }).join('');
                    };

                    const codeToCopy = extractText(node.children);
                    navigator.clipboard.writeText(codeToCopy);
                    antMessage.success('代码已复制');
                  }}
                >
                  <CopyOutlined />
                </button>
              </div>
              <pre className={className}>
                <code {...props}>{children}</code>
              </pre>
            </div>
          );
        },
        // 自定义链接在新标签页打开
        a({ children, href, ...props }) {
          return (
            <a href={href} target="_blank" rel="noopener noreferrer" {...props}>
              {children}
            </a>
          );
        }
      }}
    >
      {content}
    </ReactMarkdown>
  );
};


/**
 * AI智能对话组件 - 极简版
 * --------------------------------------
 * 核心功能：
 * - 对话历史管理（本地存储）
 * - 调用讯飞API进行流式对话
 * - 实现打字机效果展示AI回复
 * - 支持多会话管理
 */

/**
 * 主聊天组件 - 作为容器和状态管理器
 */
const Chat: React.FC = () => {
  // --- State管理 ---
  const [inputValue, setInputValue] = useState(''); // 输入框内容
  const [loading, setLoading] = useState(false);     // 是否正在等待AI响应
  const [conversations, setConversations] = useState<Conversation[]>([]); // 所有对话列表
  const [activeConversationId, setActiveConversationId] = useState<string | null>(null); // 当前活动对话ID
  const [currentMessages, setCurrentMessages] = useState<Message[]>([]); // 当前对话的消息列表
  const [sidebarCollapsed, setSidebarCollapsed] = useState(false); // 侧边栏是否折叠

  // 打字机效果相关State
  const [typewriterText, setTypewriterText] = useState(''); // 打字机显示的文本
  const [typewriterIndex, setTypewriterIndex] = useState(0); // 打字机当前字符索引

  // --- Refs ---
  const messagesEndRef = useRef<HTMLDivElement>(null); // 聊天记录末尾的引用，用于自动滚动
  const typewriterIntervalRef = useRef<NodeJS.Timeout | null>(null); // 打字机定时器引用
  const abortControllerRef = useRef<AbortController | null>(null); // 用于中止API请求的控制器

  /**
   * 示例问题数据
   * 用于在欢迎界面展示，引导用户开始对话
   */
  const exampleQuestions = [
    {
      icon: '📝',
      title: '写作助手',
      desc: '帮我写一份工作总结的大纲',
      prompt: '请帮我写一份工作总结的大纲'
    },
    {
      icon: '🤖',
      title: '技术解答',
      desc: '解释什么是人工智能',
      prompt: '解释一下什么是人工智能'
    },
    {
      icon: '💻',
      title: '编程助手',
      desc: '用Python写一个排序算法',
      prompt: '用Python写一个排序算法'
    },
    {
      icon: '💡',
      title: '创意灵感',
      desc: '给我一些创业点子',
      prompt: '给我一些互联网创业的点子'
    }
  ];

  /**
   * 滚动到聊天记录底部
   * @description 每次消息更新时调用，确保最新消息可见
   */
  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  // 监听消息变化，自动滚动
  useEffect(() => {
    scrollToBottom();
  }, [currentMessages]);

  /**
   * 组件卸载时清理打字机定时器
   */
  useEffect(() => {
    return () => {
      if (typewriterIntervalRef.current) {
        clearInterval(typewriterIntervalRef.current);
      }
    };
  }, []);

  /**
   * 从localStorage加载对话历史
   * @description 组件首次加载时执行
   */
  useEffect(() => {
    const savedConversations = localStorage.getItem('chat_conversations');
    if (savedConversations) {
      const parsed = JSON.parse(savedConversations);
      setConversations(parsed);
      // 如果没有活动对话，默认选择第一个
      if (parsed.length > 0 && !activeConversationId) {
        setActiveConversationId(parsed[0].id);
        setCurrentMessages(parsed[0].messages);
      }
    }
  }, []);

  /**
   * 保存当前所有对话到localStorage
   * @param convs - 对话列表
   */
  const saveConversations = (convs: Conversation[]) => {
    localStorage.setItem('chat_conversations', JSON.stringify(convs));
  };

  /**
   * 创建一个新的对话
   */
  const createNewConversation = () => {
    const newConversation: Conversation = {
      id: `conv_${Date.now()}`,
      title: '新对话',
      messages: [],
      createdAt: Date.now(),
      updatedAt: Date.now()
    };

    const newConversations = [newConversation, ...conversations];
    setConversations(newConversations);
    setActiveConversationId(newConversation.id);
    setCurrentMessages([]);
    setTypewriterText(''); // <-- 1. 重置打字机状态
    saveConversations(newConversations);
  };

  /**
   * 删除指定的对话
   * @param id - 要删除的对话ID
   * @param e - 点击事件
   */
  const deleteConversation = (id: string, e: React.MouseEvent) => {
    e.stopPropagation(); // 阻止事件冒泡，防止触发切换对话
    const newConversations = conversations.filter(c => c.id !== id);
    setConversations(newConversations);
    setTypewriterText(''); // <-- 2. 重置打字机状态
    saveConversations(newConversations);

    // 如果删除的是当前活动对话，则切换到新的对话
    if (activeConversationId === id) {
      if (newConversations.length > 0) {
        setActiveConversationId(newConversations[0].id);
        setCurrentMessages(newConversations[0].messages);
        setTypewriterText(''); // <-- 3. 重置打字机状态
      } else {
        // 如果没有对话了，则清空
        setActiveConversationId(null);
        setCurrentMessages([]);
        setTypewriterText(''); // <-- 3. 重置打字机状态
      }
    }
  };

  /**
   * 切换到指定的对话
   * @param id - 目标对话ID
   */
  const switchConversation = (id: string) => {
    const conversation = conversations.find(c => c.id === id);
    if (conversation) {
      setActiveConversationId(id);
      setCurrentMessages(conversation.messages);
      setTypewriterText(''); // <-- 4. 重置打字机状态
    }
  };

  /**
   * 更新当前活动对话的消息列表
   * @param messages - 最新的消息列表
   * @description 如果没有活动对话，则会创建一个新的对话
   */
  const updateCurrentConversation = (messages: Message[]) => {
    if (!activeConversationId) {
      // 如果没有活动对话，根据第一条消息创建一个新的对话
      const newConversation: Conversation = {
        id: `conv_${Date.now()}`,
        title: messages[0]?.content.substring(0, 20) || '新对话', // 使用第一条消息内容作为标题
        messages: messages,
        createdAt: Date.now(),
        updatedAt: Date.now()
      };

      const newConversations = [newConversation, ...conversations];
      setConversations(newConversations);
      setActiveConversationId(newConversation.id);
      saveConversations(newConversations);
    } else {
      // 更新现有对话
      const newConversations = conversations.map(conv => {
        if (conv.id === activeConversationId) {
          return {
            ...conv,
            messages: messages,
            updatedAt: Date.now(),
            // 如果是新对话的第一条消息，更新标题
            title: conv.messages.length === 0 && messages.length > 0
              ? messages[0].content.substring(0, 20)
              : conv.title
          };
        }
        return conv;
      });

      setConversations(newConversations);
      saveConversations(newConversations);
    }

    setCurrentMessages(messages);
  };

  /**
   * 发送消息的核心处理函数
   */
  const handleSend = async () => {
    const userMessageContent = inputValue.trim();
    if (!userMessageContent) {
      antMessage.warning('请输入消息内容');
      return;
    }

    // Abort any existing request
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }
    // Create a new controller for the new request
    abortControllerRef.current = new AbortController();

    // 1. 创建用户消息 (用于立即更新UI)
    const userMessage: Message = {
      role: 'user',
      content: userMessageContent,
      timestamp: Date.now()
    };

    const newMessages = [...currentMessages, userMessage];
    updateCurrentConversation(newMessages);
    setInputValue('');
    setLoading(true);

    // 2. 添加AI消息占位符
    const aiMessage: Message = {
      role: 'assistant',
      content: '',
      timestamp: Date.now(),
      isStreaming: true
    };

    const messagesWithAI = [...newMessages, aiMessage];
    updateCurrentConversation(messagesWithAI);

    try {
      // 3. 准备API请求的上下文
      //    - 使用'currentMessages'作为历史记录，它不包含当前发送的这一条
      //    - 将'userMessageContent'作为单独的用户消息传入
      const recentHistory = currentMessages.slice(-20);
      const context = createChatContext(
        '你是一个智能助手，请用中文回答用户的问题。', // 系统提示词
        userMessageContent,
        recentHistory
      );

      let fullContent = ''; // 用于拼接完整的AI回复
      let displayedLength = 0; // 打字机已显示的字符长度
      setTypewriterText('');
      setTypewriterIndex(0);

      // 4. 清理之前的打字机定时器
      if (typewriterIntervalRef.current) {
        clearInterval(typewriterIntervalRef.current);
        typewriterIntervalRef.current = null;
      }

      /**
       * 启动打字机效果
       * @description 使用setInterval模拟逐字打印
       */
      const startTypewriter = () => {
        if (!typewriterIntervalRef.current) {
          typewriterIntervalRef.current = setInterval(() => {
            // 只要已显示长度小于总长度，就继续显示
            if (displayedLength < fullContent.length) {
              displayedLength++;
              setTypewriterText(fullContent.substring(0, displayedLength));
              setTypewriterIndex(displayedLength);
            } else if (typewriterIntervalRef.current) {
              // 如果已经显示完所有内容，但还在流式输出中，保持定时器运行
              // 这样新内容到达时可以继续显示
            }
          }, 20); // 打字速度：每个字符20ms
        }
      };

      // 5. 调用讯飞API，处理流式响应
      await callXunfeiAPI(
        context,
        true,
        (content, isComplete) => {
          if (abortControllerRef.current?.signal.aborted) {
            return;
          }
          fullContent += content;

          // 第一次收到响应时，启动打字机
          if (!typewriterIntervalRef.current) {
            startTypewriter();
          }

          // 更新AI消息的内容和流式状态
          const updatedMessages = messagesWithAI.map((msg, index) => {
            if (index === messagesWithAI.length - 1) {
              return {
                ...msg,
                content: fullContent,
                isStreaming: !isComplete // 如果完成，则停止流式状态
              };
            }
            return msg;
          });

          updateCurrentConversation(updatedMessages);

          // 6. 流式传输完成后的处理
          if (isComplete) {
            setLoading(false);
            // 额外等待，确保打字机效果完全显示
            const waitTime = Math.max(0, (fullContent.length - displayedLength) * 20 + 100);
            setTimeout(() => {
              setTypewriterText(fullContent);
              if (typewriterIntervalRef.current) {
                clearInterval(typewriterIntervalRef.current);
                typewriterIntervalRef.current = null;
              }
            }, waitTime);
          }
        },
        abortControllerRef.current.signal // 传递 signal
      );
    } catch (error) {
      if ((error as Error).name !== 'AbortError') {
        console.error('API调用失败:', error);
        antMessage.error('消息发送失败，请重试');
        // 如果API调用失败，移除AI消息占位符
        updateCurrentConversation(newMessages);
      }
    } finally {
      // 清理工作
      if (abortControllerRef.current && !abortControllerRef.current.signal.aborted) {
         abortControllerRef.current = null;
      }
      setLoading(false);
    }
  };

  /**
   * 停止AI生成
   */
  const handleStop = () => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      setLoading(false);

      // 立即将最后一条正在流式传输的消息状态设置为 "完成"
      // 这是为了防止在快速开始新对话时，旧的流式消息仍然存在
      const lastMessage = currentMessages[currentMessages.length - 1];
      if (lastMessage && lastMessage.role === 'assistant' && lastMessage.isStreaming) {
        const updatedMessages = currentMessages.map((msg, index) => 
          index === currentMessages.length - 1 ? { ...msg, isStreaming: false } : msg
        );
        updateCurrentConversation(updatedMessages);
      }
    }
  };

  /**
   * 处理键盘事件，实现回车发送
   * @param e - 键盘事件
   */
  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault(); // 阻止默认的回车换行
      handleSend();
    }
  };

  /**
   * 渲染消息内容
   * @description 将简单的Markdown标记转换为HTML
   * @param content - 消息文本
   * @returns 渲染后的HTML元素
   */
  const renderMessageContent = (content: string) => {
    console.log("🚀 ~ renderMessageContent ~ content:", content)
    // 注意：在实际项目中，应使用更安全的Markdown渲染库（如react-markdown）
    // 以防止XSS攻击。此处为简化示例。
    return (
      <div className="message-content" dangerouslySetInnerHTML={{
        __html: content
          .replace(/\n/g, '<br/>') // 换行
          .replace(/```(.*?)```/gs, '<pre><code>$1</code></pre>') // 代码块
          .replace(/`([^`]+)`/g, '<code>$1</code>') // 行内代码
          .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>') // 粗体
          .replace(/\*(.*?)\*/g, '<em>$1</em>') // 斜体
      }} />
    );
  };

  return (
    <div className="chat-container-modern">
      <ConversationSidebar
        collapsed={sidebarCollapsed}
        conversations={conversations}
        activeConversationId={activeConversationId}
        onToggle={() => setSidebarCollapsed(!sidebarCollapsed)}
        onNew={createNewConversation}
        onSwitch={switchConversation}
        onDelete={deleteConversation}
      />

      {/* 主聊天区域 */}
      <div className="chat-main-modern">
        <div className="chat-header">
          <h2>智能助手</h2>
          <div className="header-actions">
            <div className="model-selector">
              <span className="model-icon"></span>
              <span>讯飞 Spark Max</span>
            </div>
          </div>
        </div>

        <div className="chat-messages">
          {currentMessages.length === 0 ? (
            <WelcomeScreen
              exampleQuestions={exampleQuestions}
              onExampleClick={(prompt) => setInputValue(prompt)}
            />
          ) : (
            <>
              {currentMessages.map((msg, index) => (
                <MessageCard
                  key={index}
                  message={msg}
                  typewriterText={typewriterText}
                />
              ))}
              <div ref={messagesEndRef} />
            </>
          )}
        </div>

        <ChatInput
          value={inputValue}
          loading={loading}
          onChange={(e) => setInputValue(e.target.value)}
          onKeyPress={handleKeyPress}
          onSend={handleSend}
          onStop={handleStop}
        />
      </div>
    </div>
  );
};

export default Chat;
